Skip to content

improve get_account_playlists perf#36

Merged
stereosteve merged 1 commit intomainfrom
sp-account-playlists-query
Apr 22, 2025
Merged

improve get_account_playlists perf#36
stereosteve merged 1 commit intomainfrom
sp-account-playlists-query

Conversation

@stereosteve
Copy link
Copy Markdown
Contributor

@stereosteve stereosteve commented Apr 22, 2025

  • move all filtering to CTE
  • add where p.is_delete = false to final playlist select to ensure saves of deleted playlists get filtered out correctly? Unless we need delete for the tombstones.
  • remove is_current filters... it does no filtering so can only hurt perf.
  • add second sort... this is mostly for tests where all rows get created with the same timestamp... this makes the asserts more deterministic there.

CTE often can be optimization boundaries for the query planner... I'm surprised the before plan was so much worse (100x cost estimate).

Before:

 Gather Merge  (cost=203776.94..213213.83 rows=80882 width=50)
   Workers Planned: 2
   ->  Sort  (cost=202776.92..202878.02 rows=40441 width=50)
         Sort Key: p.created_at DESC
         ->  Nested Loop  (cost=176.66..199682.47 rows=40441 width=50)
               ->  Parallel Seq Scan on playlists p  (cost=176.23..34068.44 rows=40441 width=38)
                     Filter: (is_current AND (NOT is_delete) AND ((playlist_owner_id = 1) OR (hashed SubPlan 1)))
                     SubPlan 1
                       ->  Bitmap Heap Scan on saves  (cost=9.32..176.13 rows=41 width=4)
                             Recheck Cond: (((user_id = 1) AND (save_type = 'playlist'::savetype)) OR ((user_id = 1) AND (save_type = 'album'::savetype)))
                             Filter: (is_current AND (NOT is_delete))
                             ->  BitmapOr  (cost=9.32..9.32 rows=42 width=0)
                                   ->  Bitmap Index Scan on saves_new_user_id_save_type_idx  (cost=0.00..4.85 rows=42 width=0)
                                         Index Cond: ((user_id = 1) AND (save_type = 'playlist'::savetype))
                                   ->  Bitmap Index Scan on saves_new_user_id_save_type_idx  (cost=0.00..4.44 rows=1 width=0)
                                         Index Cond: ((user_id = 1) AND (save_type = 'album'::savetype))
               ->  Index Scan using idx_user_status on users u  (cost=0.43..4.09 rows=1 width=16)
                     Index Cond: (user_id = p.playlist_owner_id)
(18 rows)

After:

 Sort  (cost=2000.34..2000.62 rows=112 width=50)
   Sort Key: p.created_at DESC
   ->  Nested Loop  (cost=542.09..1996.52 rows=112 width=50)
         ->  Nested Loop  (cost=541.66..1609.96 rows=112 width=38)
               ->  HashAggregate  (cost=541.24..542.56 rows=132 width=4)
                     Group Key: saves.save_item_id
                     ->  Append  (cost=9.32..540.91 rows=132 width=4)
                           ->  Bitmap Heap Scan on saves  (cost=9.32..176.13 rows=41 width=4)
                                 Recheck Cond: (((user_id = 1) AND (save_type = 'playlist'::savetype)) OR ((user_id = 1) AND (save_type = 'album'::savetype)))
                                 Filter: (NOT is_delete)
                                 ->  BitmapOr  (cost=9.32..9.32 rows=42 width=0)
                                       ->  Bitmap Index Scan on saves_new_user_id_save_type_idx  (cost=0.00..4.85 rows=42 width=0)
                                             Index Cond: ((user_id = 1) AND (save_type = 'playlist'::savetype))
                                       ->  Bitmap Index Scan on saves_new_user_id_save_type_idx  (cost=0.00..4.44 rows=1 width=0)
                                             Index Cond: ((user_id = 1) AND (save_type = 'album'::savetype))
                           ->  Index Scan using playlist_owner_id_idx on playlists p_1  (cost=0.42..362.80 rows=91 width=4)
                                 Index Cond: (playlist_owner_id = 1)
                                 Filter: (NOT is_delete)
               ->  Index Scan using idx_playlist_status on playlists p  (cost=0.42..8.08 rows=1 width=38)
                     Index Cond: ((playlist_id = saves.save_item_id) AND (is_delete = false))
         ->  Index Scan using idx_user_status on users u  (cost=0.43..3.44 rows=1 width=16)
               Index Cond: (user_id = p.playlist_owner_id)

@stereosteve stereosteve requested a review from schottra April 22, 2025 03:51
@stereosteve stereosteve mentioned this pull request Apr 22, 2025
@stereosteve stereosteve merged commit b8d9583 into main Apr 22, 2025
2 checks passed
@stereosteve stereosteve deleted the sp-account-playlists-query branch April 22, 2025 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant